#include "ice/stun_request.h"
#include <rtc_base/helpers.h>
#include <rtc_base/logging.h>
#include <rtc_base/string_encode.h>
#include <rtc_base/time_utils.h>
namespace xrtc
{
    // StunRequestManager
    void StunRequestManager::Send(StunRequest *request)
    {
        request->SetManager(this);
        request->Construct();
        requests_[request->Id()] = request;
        request->Send();
    }
    void StunRequestManager::Remove(StunRequest *request)
    {
        auto iter = requests_.find(request->Id());
        if (iter != requests_.end())
        {
            requests_.erase(iter);
        }
    }
    StunRequestManager::~StunRequestManager()
    {
        while (requests_.begin() != requests_.end())
        {

            StunRequest *request = requests_.begin()->second;
            requests_.erase(requests_.begin());
            delete request;
        }
    }

    bool StunRequestManager::CheckResponse(StunMessage *msg)
    {
        // 检查message有没有在缓存中存在
        auto iter = requests_.find(msg->TranscationId());
        if (iter == requests_.end())
        {

            return false;
        }
        StunRequest *request = iter->second;
        if (msg->Type() == GetStunSuccessResponse(request->Type()))
        {
            request->OnRequestResponse(msg);
        }
        else if (msg->Type() == GetStunErrorResponse(request->Type()))
        {
            request->OnRequestErrorResponse(msg);
        }
        else
        {
            RTC_LOG(LS_WARNING) << "Received Stun binding response with wrong type:"
             << msg->Type() << ", id:" << rtc::hex_encode(msg->TranscationId());
            delete request;
            return false;
        }
        delete request;
        return true;
    }

    // StunRequest
    StunRequest::StunRequest(StunMessage *msg) : msg_(msg)
    {

        msg_->SetTransationId(rtc::CreateRandomString(k_stun_transaction_id_length));
    }
    StunRequest::~StunRequest()
    {
        if (manager_)
        {
            manager_->Remove(this);
        }
        delete msg_;
        msg_ = nullptr;
    }
    int StunRequest::Elapsed()
    {
        return rtc::TimeMillis() - ts_;
    }

    void StunRequest::Construct()
    {
        Prepare(msg_);
    }
    void StunRequest::Send()
    {
        // 记录发送时间目的计算rtt
        ts_ = rtc::TimeMillis();
        rtc::ByteBufferWriter buf;
        if (!msg_->Write(&buf))
        {
            return;
        }
        manager_->SignalSendPacket(this, buf.Data(), buf.Length());
    }

} // namespace xrtc;